// 编译时优化的图像金字塔
template <typename PixelT, int Levels>
class ImagePyramid
{
    static_assert(Levels > 0, "Pyramid must have at least one level");

    // 递归定义每一层的类型
    template <int L>
    struct Level
    {
        static constexpr int scale = 1 << L;
        static constexpr int width = BaseWidth / scale;
        static constexpr int height = BaseHeight / scale;
    };

    static constexpr int BaseWidth = 640;
    static constexpr int BaseHeight = 480;

    // 使用tuple存储不同大小的图像
    using PyramidTuple = std::tuple<
        Image<PixelT, Level<0>::width, Level<0>::height>,
        Image<PixelT, Level<1>::width, Level<1>::height>,
        // ... 展开到Levels-1
        Image<PixelT, Level<Levels - 1>::width, Level<Levels - 1>::height>>;

    PyramidTuple pyramid_;

public:
    // 编译时获取特定层级的图像
    template <int L>
    auto &level()
    {
        static_assert(L >= 0 && L < Levels, "Level out of range");
        return std::get<L>(pyramid_);
    }

    // 构建金字塔
    void build(const Image<PixelT, BaseWidth, BaseHeight> &base_image)
    {
        // 设置第0层为原始图像
        level<0>() = base_image;

        // 编译时展开的降采样循环
        build_level<1>(std::make_index_sequence<Levels - 1>{});
    }

private:
    template <int L, size_t... Is>
    void build_level(std::index_sequence<Is...>)
    {
        // 展开所有层级的计算
        (downsample<L + Is>(), ...);
    }

    template <int L>
    void downsample()
    {
        auto &prev = level<L - 1>();
        auto &curr = level<L>();

        // 实际的降采样逻辑
        for (int y = 0; y < Level<L>::height; ++y)
        {
            for (int x = 0; x < Level<L>::width; ++x)
            {
                curr.at(y, x) = prev.at(y * 2, x * 2);
            }
        }
    }
};